#!/usr/bin/lua
---------
-- ## 上报数据操作模块
--
-- Dependencies: `apm4lua`, `apm_global`
-- @module ApmData
-- @author guojq
-- @copyright All Rights Reserved Copyright (C) 2014 - 2017 broada,Co.,Ltd.

require("apm4lua")
require("apm_global")

ApmData = {};

--- 获取协议类型
-- @return 协议类型(0:REQ/1:RESP/2:PUB/3:SUB/4:NIFY)
function ApmData.getMsgType()
	-- local i_ret=0;
	-- i_ret = apm4report.get_messageType(G_VAR_REPORT_DATA);
	-- return i_ret;
	return  apm4report.get_messageType(G_VAR_REPORT_DATA);
end

--- 获取l7协议号
-- @return 协议号6=TCP，17=UDP
function ApmData.getL7Proto()
	return apm4report.get_l7proto(G_VAR_REPORT_DATA);
end

--- 设置l7协议号
-- @number i_l7proto l7协议号
-- @return[1] 0(FRLUA_SUCC) 成功
-- @return[2] 1(FRLUA_FAIL) 失败
function ApmData.setL7Proto(i_l7proto)
	if type(i_l7proto) ~= "number" then
		logger:debug("parameter l7proto err");
		return FRLUA_FAIL;
	end
	return apm4report.set_l7proto(G_VAR_REPORT_DATA, i_l7proto);
end

--- 获取源IP
-- @return 源IP，例如 192.168.18.20
function ApmData.getSrcIp()
	return apm4report.get_srcIp(G_VAR_REPORT_DATA);
end

--- 设置源IP
-- @string s_src_ip 源IP
-- @return[1] 0(FRLUA_SUCC) 成功
-- @return[2] 1(FRLUA_FAIL) 失败
function ApmData.setSrcIp(s_src_ip)
	if s_src_ip == nil or type(s_src_ip) ~= "string" or s_src_ip == "" then
		logger:debug("parameter s_src_ip err");
		return FRLUA_FAIL;
	end
	return apm4report.set_srcIp(G_VAR_REPORT_DATA, s_src_ip);
end

--- 获取源port
-- @return 源端口，例如 20000
function ApmData.getSrcPort()
	return apm4report.get_srcPort(G_VAR_REPORT_DATA);
end

--- 设置源port
-- @number i_src_port 源port
-- @return[1] 0(FRLUA_SUCC) 成功
-- @return[2] 1(FRLUA_FAIL) 失败
function ApmData.setSrcPort(i_src_port)
	if i_src_port == nil or type(i_src_port) ~= "number" then
		logger:debug("parameter i_src_port err");
		return FRLUA_FAIL;
	end
	return apm4report.set_srcPort(G_VAR_REPORT_DATA, i_src_port);
end

--- 获取目的IP
-- @return 目的IP，例如 192.168.0.1
function ApmData.getDstIp()
	return apm4report.get_dstIp(G_VAR_REPORT_DATA);
end

--- 设置目的IP
-- @number s_dst_ip 目的IP
-- @return[1] 0(FRLUA_SUCC) 成功
-- @return[2] 1(FRLUA_FAIL) 失败
function ApmData.setDstIp(s_dst_ip)
	if s_dst_ip == nil or type(s_dst_ip) ~= "string" or s_dst_ip == "" then
		logger:debug("parameter s_dst_ip err");
		return FRLUA_FAIL;
	end
	return apm4report.set_dstIp(G_VAR_REPORT_DATA, s_dst_ip);
end

--- 获取目的端口
-- @return 目的端口，例如 80
function ApmData.getDstPort()
	return apm4report.get_dstPort(G_VAR_REPORT_DATA);
end

--- 设置目的端口
-- @number i_dst_port 目的端口
-- @return[1] 0(FRLUA_SUCC) 成功
-- @return[2] 1(FRLUA_FAIL) 失败
function ApmData.setDstPort(i_dst_port)
	if i_dst_port == nil or type(i_dst_port) ~= "number" then
		logger:debug("parameter i_dst_port err");
		return FRLUA_FAIL;
	end
	return apm4report.set_dstPort(G_VAR_REPORT_DATA, i_dst_port);
end

--- 获取指定数组大小
-- @string p_key 字段名 eg. "request.isResponseRequired"
-- @return[1] 0 出错
-- @return[2] 其他 数组大小
function ApmData.getFieldSize(p_key)
	if type(p_key) ~= "string" then
		return 0;
	end
	return apm4report.get_fieldSize(G_VAR_REPORT_DATA, p_key);
end

--- 获取指定字段名，指定位置的内容
-- @string p_key 字段名 eg. "request.isResponseRequired"
-- @number i_index Index表示V数组下标，从1开始
-- @treturn[1] string 取得的内容
-- @return[2] nil
function ApmData.getField(p_key, i_index)
	if type(p_key) ~= "string" or type(i_index) ~= "number" then
		logger:debug("parameter p_key/i_index err");
		return nil;
	end

	if i_index <= 0 then
		logger:debug("parameter i_index err");
		return nil;
	end

	i_index = i_index - 1;
	return apm4report.get_field(G_VAR_REPORT_DATA, p_key, i_index);
end

--- 增加字段
-- @string p_key 字段名 eg. "connection.syn_time_us"
-- @tparam string|number p_value 字段内容 eg. 600
-- @return[1] 0(FRLUA_SUCC) 成功
-- @return[2] 1(FRLUA_FAIL) 失败
-- @usage
--   addField("transaction.title", "test001")
--   addField("connection.syn_time_us", 600)
--   addField("connection.syn_time_us", 11.12)
function ApmData.addField(p_key, p_value)
	if type(p_key) ~= "string" then
		logger:debug("parameter p_key err");
		return FRLUA_FAIL;
	end

	if type(p_value) == "number" then
		if math.floor(p_value) < p_value then
			-- 小数
			return apm4report.add_fieldDouble(G_VAR_REPORT_DATA, p_key, p_value);
		else
			return apm4report.add_fieldLong(G_VAR_REPORT_DATA, p_key, p_value);
		end
	elseif type(p_value) == "string" then
		return apm4report.add_fieldStr(G_VAR_REPORT_DATA, p_key, p_value);
	else
		logger:debug("parameter p_value err");
		return FRLUA_FAIL;
	end
end

--- 删除字段
-- @string p_key 字段名 eg. "connection.syn_time_us"
-- @return[1] 0(FRLUA_SUCC) 成功
-- @return[2] 1(FRLUA_FAIL) 失败
function ApmData.delFields(p_key)
	if type(p_key) ~= "string" then
		logger:debug("parameter p_key err");
		return FRLUA_FAIL;
	end

	return apm4report.del_fieldAll(G_VAR_REPORT_DATA, p_key);
end

--- 删除字段(指定位置)
-- @string p_key 字段名 eg. "connection.syn_time_us"
-- @number i_index Index表示V数组下标，从1开始
-- @return[1] 0(FRLUA_SUCC) 成功
-- @return[2] 1(FRLUA_FAIL) 失败
function ApmData.delField(p_key, i_index)
	if type(p_key) ~= "string" or type(i_index) ~= "number" then
		logger:debug("parameter p_key/i_index err");
		return FRLUA_FAIL;
	end

	if i_index <= 0 then
		logger:debug("parameter i_index err");
		return FRLUA_FAIL;
	end

	i_index = i_index - 1;
	return apm4report.del_fieldIndex(G_VAR_REPORT_DATA, p_key, i_index);
end

--- 替换字段
-- @string p_key 字段名 eg. "connection.syn_time_us"
-- @tparam string|number p_value 字段内容 eg. 600
-- @return[1] 0(FRLUA_SUCC) 成功
-- @return[2] 1(FRLUA_FAIL) 失败
-- @usage
--   replaceField("transaction.title", "test001")
--   replaceField("connection.syn_time_us", 600)
--   replaceField("connection.syn_time_us", 11.12)
function ApmData.replaceField(p_key, p_value)
	local i_ret=FRLUA_FAIL;
	if type(p_key) ~= "string" then
		logger:debug("parameter p_key err");
		return FRLUA_FAIL;
	end

	-- 清除老字段
	if type(p_value) == "number" or type(p_value) == "string" then
		ApmData.delFields(p_key);
		i_ret = ApmData.addField(p_key, p_value);
		return i_ret;
	end

	return FRLUA_FAIL;
end

--- 判断协议解码模块中是否存在某个key
-- @string p_key 字段名 eg. "request.isResponseRequired"
-- @return[1] true 存在
-- @return[2] false 出错或不存在
function ApmData.exists(p_key)
	local i_ret_fun=0;
	if type(p_key) ~= "string" then
		logger:debug("parameter p_key err");
		return false;
	end

	i_ret_fun = apm4report.get_existsField(p_key);
	if i_ret_fun ~= 0 then
		return true;
	else
		return false;
	end
end

--- 将所有字段输出到文本
-- @tparam bool|number b_style 格式化输出 true/1; 否则 false/0
-- @treturn[1] string 文本
-- @treturn[2] nil 出错
function ApmData.dumpFields(b_style)
	if type(b_style) ~= "boolean" and type(b_style) ~= "number" then
		logger:debug("parameter p_key err");
		return nil;
	end

	if type(b_style) == "boolean" then
		if b_style == true then
			return apm4report.dumpField(G_VAR_REPORT_DATA, 1);
		else
			return apm4report.dumpField(G_VAR_REPORT_DATA, 0);
		end
	end

	if type(b_style) == "number" then
		if b_style ~= 0 then
			return apm4report.dumpField(G_VAR_REPORT_DATA, 1);
		else
			return apm4report.dumpField(G_VAR_REPORT_DATA, 0);
		end
	end

	return nil;
end

return ApmData;
